package org.vnl.platform.spring.mvc;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.vnl.platform.dk.util.PDKException;
import org.vnl.platform.dk.util.PDKRuntimeException;
import org.vnl.platform.orm.PersistenceManagerFactory;
import org.vnl.platform.orm.TransactionException;

/**
 * 使用spring的MVC時,可以讓所有Controller去繼承這個因而有統一處理Exception的方式.
 * 
 * @author Vaughan
 *
 */
abstract public class AbstractController {
    private static final Logger logger = Logger.getLogger(AbstractController.class);
    
    @ExceptionHandler (TransactionException.class)
    public ModelAndView handleTransactionException(HttpServletRequest req,  HttpServletResponse resp, TransactionException ex, Locale locale) {
        logger.error("TransactionException",ex);
        try {
            PersistenceManagerFactory.getInstance().getCurrentPM().setRollbackOnly(true);
        } catch (TransactionException e) {
            logger.fatal("Cannot rollback transaction",e);
        }
        ModelAndView mav = new ModelAndView();
        createPageInfo(getExceptionStatus(), ex.getMessage(), getExceptionLocalizedMessage(ex, locale), mav);
        mav.setViewName(getErrorViewName());
        return mav;
    }
    
    abstract protected String getExceptionStatus();

    abstract protected String getErrorViewName();
    
    protected String getExceptionLocalizedMessage(PDKException e, Locale locale) {
        return e.getLocalizedMessage(locale);
    }

    protected String getExceptionLocalizedMessage(PDKRuntimeException e, Locale locale) {
        return e.getLocalizedMessage(locale);
    }
    
    abstract protected void createPageInfo(String status, String responseCode, String description, ModelAndView mav);
}
